package com.well.register.cluster;

import com.well.register.data.ClusterDataCenter;
import com.well.register.data.DataCenter;
import com.well.rpc.model.ClusterServerModel;
import com.well.rpc.model.EnumServerStatus;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <h>集群选举</h>
 * <p> 选举思想比较简单，比如一个国家，有国王，有储君，有大臣，有平民...</p>
 * <p> 本程序以此为思想，在集群中同样有如此的等级。等级制度是按照年龄进行区分</p>
 * <p> 国王负责调度，而其他节点根据职位不同负责不同程度工作，但是当集群节点只有国王，</p>
 * <p> 储君，大臣时，国王也要一定程度进行工作</p>
 */
public class ClusterVote {

    /**
     * 一般是集群刚开始启动时，或者集群领导挂之后补位
     * 集群选举
     */
    public Set<ClusterServerModel> comparatorAge(ConcurrentHashMap<String, ClusterServerModel> clusterServerModels) {
        Enumeration<ClusterServerModel> elements = clusterServerModels.elements();
        Set<ClusterServerModel> models = new TreeSet<>(new ClusterComparator());
        while (elements.hasMoreElements()) {
            ClusterServerModel clusterServerModel = elements.nextElement();
            models.add(clusterServerModel);
        }
        return models;
    }

    public synchronized void setPower() {
        ConcurrentHashMap<String, ClusterServerModel> clusters = ClusterDataCenter.getClusters();
        Set<ClusterServerModel> models = comparatorAge(clusters);
        Iterator<ClusterServerModel> iterator = models.iterator();
        Integer status = EnumServerStatus.KING.getStatus();
        while (iterator.hasNext()) {
            ClusterServerModel next = iterator.next();
            String key = next.getHost() + next.getPort();
            ClusterServerModel clusterServerModel = clusters.get(key);
            if (status < EnumServerStatus.PREMIER.getStatus()) {
                clusterServerModel.setStatus(status);
                status++;
            } else {
                clusterServerModel.setStatus(EnumServerStatus.PEOPLE.getStatus());
            }
            if ((DataCenter.getHost() + DataCenter.getPort()).equals(key)) {
                ClusterDataCenter.setStatus(clusterServerModel.getStatus());
            }
        }
    }


    private class ClusterComparator implements Comparator<ClusterServerModel> {

        @Override
        public int compare(ClusterServerModel o1, ClusterServerModel o2) {
            return (int) (o2.getAge() - o1.getAge());
        }
    }
}
